package com.lagou.utils;


import com.lagou.client.RpcConsumer;
import java.util.*;

public class RequestMetrics {

    private static Map<String,Metrics> requestMap = new HashMap<>();
    public static Map<String,Long> costMap = new HashMap<>();

    public static void put(String ip,Integer port,String requestId){
        requestMap.put(requestId,new Metrics(ip,port,System.currentTimeMillis()));
    }

    public static void addNode(String address){
        costMap.put(address,0l);
    }

    public static void removeNode(String ip, Integer port){
        costMap.remove(ip+":"+port);
    }

    public static void calculate(String requestId){
        Metrics metrics = requestMap.get(requestId);
        long cost = System.currentTimeMillis() - metrics.getStart();
        costMap.put(metrics.getIp()+":"+metrics.getPort(),cost);
        requestMap.remove(requestId);
        RpcConsumer.zkClient.writeData("/provider/"+metrics.getIp()+":"+metrics.getPort(),metrics.getStart()+","+cost);
    }

    public static void getData(){
        List<String> children = RpcConsumer.zkClient.getChildren("/provider");
        for (String child : children) {
            if(RpcConsumer.zkClient.readData("/provider/"+child)==null){
                continue;
            }
            String[] time = RpcConsumer.zkClient.readData("/provider/"+child).toString().split(",");
            long cost;
            if((System.currentTimeMillis()-Long.valueOf(time[0]))>5000){
                cost = 0L;
            }else{
                cost = Long.valueOf(time[1]);
            }
            costMap.put(child,cost);
        }
    }

    public static String selector(){
        getData();
        if(costMap.size()==0){
            return null;
        }
        Collection<Long> c = costMap.values();
        long time = Collections.min(c);
        List<String> list = new ArrayList<>();
        costMap.forEach((key,values)->{
            if(values==time){
                list.add(key);
            }
        });
        if(list.size()==1){
            return list.get(0);
        }else{
            //load balancing logic
            Random r = new Random();
            return list.get(r.nextInt(list.size()));
        }
    }
}
